/*****************************************************************************
*
*  PROJECT:     Native Executive
*  LICENSE:     See LICENSE in the top level directory
*  FILE:        NativeExecutive/CExecutiveManager.fiber.internal.h
*  PURPOSE:     Fiber environment internals
*  DEVELOPERS:  Martin Turski <wordwhirl@outlook.de>
*
*  Multi Theft Auto is available from http://www.multitheftauto.com/
*
*****************************************************************************/

#ifndef _EXECUTIVE_MANAGER_FIBER_INTERNAL_
#define _EXECUTIVE_MANAGER_FIBER_INTERNAL_

BEGIN_NATIVE_EXECUTIVE

struct CFiberImpl : public CFiber, public FiberStatus
{
    CFiberImpl( CExecutiveManagerNative *manager, CExecutiveGroupImpl *group, Fiber *runtime )
    {
        // Using "this" is actually useful.
        this->runtime = runtime;
        this->callee = ExecutiveFiber::makefiber();

        this->has_term_exception = false;

        this->manager = manager;
        this->group = group;

        this->status = FIBER_SUSPENDED;
    }

    CExecutiveManagerNative *manager;

    Fiber *runtime;                 // storing Fiber runtime context
    void *userdata;

    bool has_term_exception;
    std::exception_ptr last_exception;  // if a C++ exception caused the Fiber to terminate.

    fiberexec_t callback;               // routine set by the fiber request.

    RwListEntry <CFiberImpl> node;      // node in fiber manager
    RwListEntry <CFiberImpl> groupNode; // node in fiber group

    CExecutiveGroupImpl *group;         // fiber group this fiber is in.

    double resumeTimer;
};

// Thread fiber stack iterator.
struct threadFiberStackIterator
{
    threadFiberStackIterator( CExecThreadImpl *thread );
    ~threadFiberStackIterator( void );

    bool IsEnd( void ) const;
    void Increment( void );

    CFiberImpl* Resolve( void ) const;

private:
    CExecThreadImpl *thread;

    size_t iter;
};

END_NATIVE_EXECUTIVE

#endif //_EXECUTIVE_MANAGER_FIBER_INTERNAL_